﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace DataNatTool
{
    public class DataNat
    {
        public event EventHandler<OnlineColorEventArgs> OnOnlineColorSent; // 定义事件

        TcpService service = new TcpService();
        TcpClient tcpClientLeft = new TcpClient();
        TcpClient tcpClientRight = new TcpClient();

        private int PortLeft = 0;
        private int PortRight = 0;

        private int SelectedIndexLeft = 0;
        private int SelectedIndexRight = 0;

        public DataNat()
        {
            //
            service.Connecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在连接
            service.Connected = (client, e) =>
            {
                client.ResetId($"ServicePort:{client.ServicePort}-IPPort:{client.IP}:{client.Port}-{DateTime.Now.ToString("HH:mm:ss:ffff")}");
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            service.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在断开连接，只有当主动断开时才有效。
            service.Disconnected = (client, e) =>
            {
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            service.Received = (client, e) =>
            {
                var ids = service.GetIds();
                foreach (var id in ids)
                {
                    if (!id.Contains($"ServicePort:{client.ServicePort}"))
                    {
                        service.Send(id, e.ByteBlock);
                    }
                }
                if (tcpClientLeft.Online)
                {
                    tcpClientLeft.Send(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);
                }
                if (tcpClientRight.Online)
                {
                    tcpClientRight.Send(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);
                }

                return EasyTask.CompletedTask;
            };
            //启动
            service.Setup(new TouchSocketConfig());
            service.Start();


            tcpClientLeft.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器，此时已经创建socket，但是还未建立tcp
            tcpClientLeft.Connected = (client, e) =>
            {
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            tcpClientLeft.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。
            tcpClientLeft.Disconnected = (client, e) =>
            {
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            tcpClientLeft.Received = (client, e) =>
            {
                var ids = service.GetIds();
                foreach (var id in ids)
                {
                    service.Send(id, e.ByteBlock);
                }
                if (tcpClientRight.Online)
                {
                    tcpClientRight.Send(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);
                }
                return EasyTask.CompletedTask;
            };


            tcpClientRight.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器，此时已经创建socket，但是还未建立tcp
            tcpClientRight.Connected = (client, e) =>
            {
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            tcpClientRight.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。
            tcpClientRight.Disconnected = (client, e) =>
            {
                SentOnlineColor();
                return EasyTask.CompletedTask;
            };
            tcpClientRight.Received = (client, e) =>
            {
                var ids = service.GetIds();
                foreach (var id in ids)
                {
                    service.Send(id, e.ByteBlock);
                }
                if (tcpClientLeft.Online)
                {
                    tcpClientLeft.Send(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);
                }
                return EasyTask.CompletedTask;
            };
        }

        public void OpenLeft_ToggledChanged(int selectedIndex, bool toggled, params string[] values)
        {
            try
            {
                PortLeft = Convert.ToInt32(values[1]);
                SelectedIndexLeft = selectedIndex;

                if (toggled)
                {
                    if (selectedIndex == 0)
                    {
                        service.AddListen(new TcpListenOption()
                        {
                            IpHost = $"{values[0]}:{values[1]}",
                            Name = "server1",//名称用于区分监听
                        });
                    }
                    else if (selectedIndex == 1)
                    {
                        tcpClientLeft.Setup(new TouchSocketConfig().SetRemoteIPHost($"{values[0]}:{values[1]}").ConfigurePlugins(a =>
                        {
                            a.UseReconnection(-1, true, 1000);
                        }));
                        tcpClientLeft.Connect();
                    }
                }
                else
                {
                    foreach (var item in service.Monitors)
                    {
                        if (item.Option.IpHost.Port == Convert.ToInt32(values[1]))
                        {
                            service.RemoveListen(item);
                        }
                    }

                    tcpClientLeft.Close();
                }
            }
            catch (Exception)
            {

            }
        }

        public void OpenRight_ToggledChanged(int selectedIndex, bool toggled, params string[] values)
        {
            try
            {
                PortRight = Convert.ToInt32(values[1]);
                SelectedIndexRight = selectedIndex;

                if (toggled)
                {
                    if (selectedIndex == 0)
                    {
                        service.AddListen(new TcpListenOption()
                        {
                            IpHost = $"{values[0]}:{values[1]}",
                            Name = "server2",//名称用于区分监听
                        });
                    }
                    else if (selectedIndex == 1)
                    {
                        tcpClientRight.Setup(new TouchSocketConfig().SetRemoteIPHost($"{values[0]}:{values[1]}").ConfigurePlugins(a =>
                        {
                            a.UseReconnection(-1, true, 1000);
                        }));
                        tcpClientRight.Connect();
                    }
                }
                else
                {
                    foreach (var item in service.Monitors)
                    {
                        if (item.Option.IpHost.Port == Convert.ToInt32(values[1]))
                        {
                            service.RemoveListen(item);
                        }
                    }
                    tcpClientRight.Close();
                }
            }
            catch (Exception)
            {

            }
        }

        public Tuple<int, int> GetIdsCount()
        {
            var ids = service.GetIds();
            var leftCount = 0;
            var rightCount = 0;

            if (SelectedIndexLeft == 0)
                leftCount = ids.Where(it => it.Contains($"ServicePort:{PortLeft}")).Count();
            else if (SelectedIndexLeft == 1)
                if (tcpClientLeft.Online)
                    leftCount = 1;
                else
                    leftCount = 0;

            if (SelectedIndexRight == 0)
                rightCount = ids.Where(it => it.Contains($"ServicePort:{PortRight}")).Count();
            else if (SelectedIndexRight == 1)
                if (tcpClientRight.Online)
                    rightCount = 1;
                else
                    rightCount = 0;

            return new Tuple<int, int>(leftCount, rightCount);
        }

        //变灯
        private void SentOnlineColor()
        {
            var res = GetIdsCount();
            // 触发事件
            //OnOnlineColorSent?.Invoke(this, new OnlineColorEventArgs(PortLeft, res.Item1));
            //OnOnlineColorSent?.Invoke(this, new OnlineColorEventArgs(PortRight, res.Item2));

            OnOnlineColorSent?.Invoke(this, new OnlineColorEventArgs(res.Item1, res.Item2));
        }

    }
}
